from django.shortcuts import render,redirect,reverse
from django.views import View
from django import http
import re
from django.db import DatabaseError
from django.contrib.auth import login,logout
from django_redis import get_redis_connection

from apps.users.models import User
from fight.utils.response_code import RETCODE

# Create your views here.


class MobileCountView(View):
    """判断手机号是否重复注册"""
    def get(self,request,mobile):

        count = User.objects.filter(mobile=mobile).count()
        return http.JsonResponse({"code":RETCODE.OK,"errmsg":"OK","count":count})


class UsernameCountView(View):
    """判断用户名是否重复注册"""

    def get(self,request,username):
        """查询用户名对应记录的个数
            username:当前要判断是否重名的用户名
        """
        # 接收参数
        # 校验参数
        #　前两步路井参数已经解决

        # 核心逻辑: 查询数据库
        # get:返回的是模型类对象,没有count方法
        # filter返回的查询集<QuerySet>
        count = User.objects.filter(username=username).count()
        # 响应结果
        return http.JsonResponse({"code":RETCODE.OK,"errmsg":"ok","count":count})


class RegisterView(View):
    """用户注册"""

    def get(self,request):
        """提供用户注册页面"""
        return render(request, "register.html")

    def post(self,request):
        """实现用户注册逻辑"""
        # 接收参数:前端发送参数的方式决定了后端读取参数的方式,本次是post表单参数
        username = request.POST.get("username")
        password = request.POST.get("password")
        password2 = request.POST.get("password2")
        mobile = request.POST.get("mobile")
        sms_code_client = request.POST.get("sms_code")
        allow = request.POST.get("allow")
        # 校验参数:前后端校验要分开,且校验逻辑要一致,后端的校验大于等于前端校验逻辑
        # 判断参数是否齐全
        # all判断一些数据是否为空,如果任意数据为空,就返回false,只有全部数据都不为空返回True
        if not all([username, password, password2, mobile, sms_code_client , allow]):
            return http.HttpResponseForbidden('缺少必传参数')
        # 判断用户名是否是5-20个字符
        if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username):
            return http.HttpResponseForbidden('请输入5-20个字符的用户名')
        # 判断密码是否是8-20个数字
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return http.HttpResponseForbidden('请输入8-20位的密码')
        # 判断两次密码是否一致
        if password != password2:
            return http.HttpResponseForbidden('两次输入的密码不一致')
        # 判断手机号是否合法
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseForbidden('请输入正确的手机号码')
        # 判断是否勾选用户协议
        if allow != 'on':
            return http.HttpResponseForbidden('请勾选用户协议')

        # 补充短信验证
        # 从redis读取短信验证码
        redis_conn = get_redis_connection("verify_code")
        sms_code_server = redis_conn.get("sms_%s" %mobile)
        if sms_code_server is None:
            return render(request,"register.html",{"sms_code_errmsg":"短信验证码失效"})
        # 对比短信验证码
        sms_code_server = sms_code_server.decode()
        if sms_code_client != sms_code_server:
            return render(request,"register.html",{"sms_code_errmsg":"短信验证码失效"})


        # 核心逻辑：　保存用户注册的数据
        # Django的用户认证系统提供的方法
        try:
            user = User.objects.create_user(username=username, password=password, mobile=mobile)
        except DatabaseError:
            return render(request,"register.html",{"register_errmsg":"注册失败"})

        # 状态保持:注册成功,即为登陆成功,登陆的本质就是做状态保持
        # login()方法默认将状态保持信息写入到浏览器和服务端的数据库(redis:1)
        login(request,user)

        # 响应结果:注册成功重定向到首页
        # return http.HttpResponse("注册成功")
        # return redirect(reverse("子应用总路由的命名空间:自路由命名空间"))
        return redirect(reverse("contents:index"))


"""
查询字符串参数: request.GET
POST表单参数: request.POST
JSON数据: request.body
COOKIES数据:request.COOKIES
文件数据: request.file
请求头: request.META
当前发送请求的用户信息: request.user
"""